package org.goldenport.g3.channels.googleApps

import java.io.{InputStream, File}
import java.net.URL
import org.goldenport.wpath._
import org.goldenport.g3._
import org.goldenport.g3.atom._
import org.goldenport.g3.messages._
import org.goldenport.g3.adapters.{G3FileStoreAdapter, G3FileStoreDriver}
import org.goldenport.g3.services.gdata._
import com.google.gdata.client.GoogleService
import com.google.gdata.client.docs._
import com.google.gdata.data._
import com.google.gdata.data.docs._
import com.asamioffice.goldenport.io.UFile

/**
 * @since   Jun. 20, 2010
 * @version Sep. 18, 2010
 * @author  ASAMI, Tomoharu
 */
class GCalendarAdapter() extends G3Adapter() with GServiceContext {
  protected override def do_Action(content: AnyRef, parcel: G3Parcel, ctx: G3AgentContext): AnyRef = {
    val cal = new GCalendarService("g3")
    setup_auth(cal.g)
    val feed = cal.getGFeed("http://www.google.com/calendar/feeds/default/allcalendars/full")
    feed
  }
}

class GDocsAdapter() extends G3FileStoreAdapter() {
  def create_Driver() = new GDocsDriver
}

class GDocsDriver extends G3FileStoreDriver with GServiceContext {
  var docs_service_option: Option[DocsService] = None
  lazy val docs_service = docs_service_option.get

  override def open() {
    val docs = new DocsService("g3")
    setup_auth(docs)
    docs_service_option = Some(docs)
  }

  protected def create_File(container: WPath, filename: String) = {
    val dirname = container.pathname
    val newEntry = new DocumentEntry()
    newEntry.setTitle(new PlainTextConstruct(filename))
    Some(docs_service.insert(new URL("https://docs.google.com/feeds/default/private/full/"), newEntry))
  }

  protected def create_File(container: WPath, filename: String, in: InputStream) = {
    error("not supported yet.")
  }

  protected def create_File(container: WPath, filename: String, string: String) = {
    val dirname = container.pathname
    val dir = work_directory()
    val file = new File(dir, filename)
    UFile.createFile(file, string, text_encoding)
    val newEntry = new DocumentEntry()
    newEntry.setTitle(new PlainTextConstruct(filename))
    newEntry.setFile(file, "text/plain")
    docs_service.insert(new URL("https://docs.google.com/feeds/default/private/full/"), newEntry)
  }

  protected def read_Files(wpath: WPath): AnyRef = {
    error("???")
  }

  protected def write_File(wpath: WPath, id: String): AnyRef = {
    error("???")
    
  }

  protected def write_File(wpath: WPath, id: String, string: String): AnyRef = {
    error("???")
    
  }

  protected def write_File(wpath: WPath, id: String, in: InputStream): AnyRef = {
    error("???")
    
  }

  protected def remove_File(wpath: WPath): AnyRef = {
    error("???")
    
  }
}

trait GServiceContext extends G3Contextable {
  val GOOGLEAPPS = "http://google.com/"
  lazy val auth = context.getAuthentication(GOOGLEAPPS)

  protected final def setup_auth(docs: GoogleService) = {
    auth match {
      case Some(bauth: BasicAuthentication) => {
        val user = bauth.user
        val password = bauth.password
        docs.setUserCredentials(user, password)
      }
      case Some(oauth: OAuthAuthentication) => {
        error(auth.toString) // XXX
      }
      case None => error(auth.toString)
    }    
  }
}

trait GoogleAppsContext extends G3Module {
  def gcalendar(atom: Symbol): G3Channel = {
    add_channel_node(atom, context.createChannel(new GCalendarAdapter()))
  }

  def gdocs(atom: Symbol): G3Channel = {
    add_channel_node(atom, context.createChannel(new GDocsAdapter()))
  }
}
